/**
 * Copyright (c) <2010>, <SUNNY GUPTA>
 * All rights reserved.

 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of the <ORGANIZATION> nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <SUNNY GUPTA> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.gwtp.investmentadvisor.client.gui.authentication;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.HasBlurHandlers;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.dom.client.HasKeyPressHandlers;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.gwtp.investmentadvisor.client.resources.AppResources;

/**
 * 
 * @author Sunny Gupta
 *
 */
public class SignUpScreenView extends Composite 
    implements SignUpScreenPresenter.Display {

  // TODO: Improve messages
  private static final String INVALID_EMAIL_MESSAGE = "Invalid Email Address";
  private static final String EMAIL_MISMATCH_MESSAGE = "The email address provided here doesn't match above email address";
  private static final String PASSWORD_MISMATCH_MESSAGE = "The password provided here doesn't match above password";
  private static final String USERNAME_AVAILABLE_MESSAGE = "The username is available";
  private static final String USERNAME_NOT_AVAILABLE_MESSAGE = "The username is not available";
  private static final String USERNAME_AVAILABLE_IN_PROGRESS_MESSAGE = "Checking username availability";

  private static SignUpScreenViewUiBinder uiBinder = GWT
      .create(SignUpScreenViewUiBinder.class);

  interface SignUpScreenViewUiBinder extends
      UiBinder<Widget, SignUpScreenView> {
  }

  @UiField
  TextBox nameTextBox;
  
  @UiField
  TextBox usernameTextBox;
  
  @UiField
  TextBox confirmUsernameTextBox;
  
  @UiField
  PasswordTextBox passwordTextBox;
  
  @UiField
  PasswordTextBox confirmPasswordTextBox;
  
  @UiField(provided = true)
  Image usernameErrorImage;
  
  @UiField(provided = true)
  Image confirmUsernameErrorImage;
  
  @UiField(provided = true)
  Image passwordErrorImage;
  
  @UiField(provided = true)
  Image confirmPasswordErrorImage;
  
  @UiField
  Label usernameErrorLabel;
  
  @UiField
  Label confirmUsernameErrorLabel;
  
  @UiField
  Label passwordErrorLabel;
  
  @UiField
  Label confirmPasswordErrorLabel;
  
  @UiField
  Button signUpButton;
    
  @UiField(provided = true)
  Image messageImage;
  
  @UiField
  Label messageLabel;
  
  @UiField(provided = true)
  AppResources resources;
  
  @Inject
  public SignUpScreenView() {
    // Provide resources
    this.resources = AppResources.INSTANCE;
    
    // Initialize error images
    this.usernameErrorImage = new Image(resources.wrongIcon());
    this.passwordErrorImage = new Image(resources.wrongIcon());
    this.confirmUsernameErrorImage = new Image(resources.wrongIcon());
    this.confirmPasswordErrorImage = new Image(resources.wrongIcon());
    this.messageImage = new Image();
    
    // Initialize widgets
    initWidget(uiBinder.createAndBindUi(this));
    
    // Configure fiels
    configureFields();
  }

  private void configureFields() {  
    // Clear All errors
    clearUsernameError();
    clearPasswordError();
    clearConfirmUsernameError();
    clearConfirmPasswordError();
  }

  private void clearConfirmPasswordError() {
    confirmPasswordErrorImage.setVisible(false);
    confirmPasswordErrorLabel.setVisible(false);
  }

  private void clearConfirmUsernameError() {
    confirmUsernameErrorImage.setVisible(false);
    confirmUsernameErrorLabel.setVisible(false);
  }

  private void clearPasswordError() {
    passwordErrorImage.setVisible(false);
    passwordErrorLabel.setVisible(false);
  }

  private void clearUsernameError() {
    usernameErrorImage.setVisible(false);
    usernameErrorLabel.setVisible(false);
  }

  @Override
  public Widget asWidget() {
    return this;
  }

  @Override
  public HasValue<String> getConfirmPasswordText() {
    return confirmPasswordTextBox;
  }

  @Override
  public HasValue<String> getConfirmUsernameText() {
    return confirmUsernameTextBox;
  }

  @Override
  public HasValue<String> getPasswordText() {
    return passwordTextBox;
  }

  @Override
  public HasBlurHandlers getUsernameBlurEventProvider() {
    return usernameTextBox;
  }

  @Override
  public HasValue<String> getUsernameText() {
    return usernameTextBox;
  }

  @Override
  public HasBlurHandlers getConfirmUsernameBlurEventProvider() {
    return confirmUsernameTextBox;
  }

  @Override
  public void showInvalidConfirmUsername() {
    this.confirmUsernameErrorImage.setResource(resources.wrongIcon());
    this.confirmUsernameErrorLabel.setText(INVALID_EMAIL_MESSAGE);
    this.confirmUsernameErrorImage.setVisible(true);
    this.confirmUsernameErrorLabel.setVisible(true);
  }

  @Override
  public void showInvalidUsername() {
    this.usernameErrorImage.setResource(resources.wrongIcon());
    this.usernameErrorLabel.setText(INVALID_EMAIL_MESSAGE);
    this.usernameErrorImage.setVisible(true);
    this.usernameErrorLabel.setVisible(true);
  }

  @Override
  public void showUsernameMismatch() {
    this.confirmUsernameErrorImage.setResource(resources.wrongIcon());
    this.confirmUsernameErrorLabel.setText(EMAIL_MISMATCH_MESSAGE);
    this.confirmUsernameErrorImage.setVisible(true);
    this.confirmUsernameErrorLabel.setVisible(true);
  }

  @Override
  public void clearInvalidConfirmUsername() {
    this.confirmUsernameErrorImage.setVisible(false);
    this.confirmUsernameErrorLabel.setVisible(false);
  }

  @Override
  public void clearInvalidUsername() {
    this.usernameErrorImage.setVisible(false);
    this.usernameErrorLabel.setVisible(false);
  }

  @Override
  public void clearUsernameMismatch() {
    this.confirmUsernameErrorImage.setVisible(false);
    this.confirmUsernameErrorLabel.setVisible(false);
  }

  @Override
  public void disableSignUpButton() {
    this.signUpButton.setEnabled(false);
  }

  @Override
  public void enableSignUpButton() {
    this.signUpButton.setEnabled(true);
  }

  @Override
  public HasValue<String> getNameText() {
    return this.nameTextBox;
  }

  @Override
  public void clearInvalidConfirmPassword() {
    this.confirmPasswordErrorImage.setVisible(false);
    this.confirmPasswordErrorLabel.setVisible(false);
  }

  @Override
  public void clearInvalidPassword() {
    this.passwordErrorImage.setVisible(false);
    this.passwordErrorLabel.setVisible(false);
  }

  @Override
  public void showInvalidConfirmPassword() {
    this.confirmPasswordErrorImage.setResource(resources.wrongIcon());
    this.confirmPasswordErrorLabel.setText(UserAuthenticationConstants.MINIMUM_PASSWORD_LENGTH_ERROR_MESSAGE);
    this.confirmPasswordErrorImage.setVisible(true);
    this.confirmPasswordErrorLabel.setVisible(true);
  }

  @Override
  public void showInvalidPassword() {
    this.passwordErrorImage.setResource(resources.wrongIcon());
    this.passwordErrorLabel.setText(UserAuthenticationConstants.MINIMUM_PASSWORD_LENGTH_ERROR_MESSAGE);
    this.passwordErrorImage.setVisible(true);
    this.passwordErrorLabel.setVisible(true);
  }

  @Override
  public void showPasswordMismatch() {
    this.confirmPasswordErrorImage.setResource(resources.wrongIcon());
    this.confirmPasswordErrorLabel.setText(PASSWORD_MISMATCH_MESSAGE);
    this.confirmPasswordErrorImage.setVisible(true);
    this.confirmPasswordErrorLabel.setVisible(true);
  }

  @Override
  public void clearPasswordMismatch() {
    this.confirmPasswordErrorImage.setVisible(false);
    this.confirmPasswordErrorLabel.setVisible(false);
  }

  @Override
  public HasKeyPressHandlers getConfirmPasswordTextKeyPressProvider() {
    return this.confirmPasswordTextBox;
  }

  @Override
  public HasKeyPressHandlers getConfirmUsernameTextKeyPressProvider() {
    return this.confirmUsernameTextBox;
  }

  @Override
  public HasKeyPressHandlers getNameTextKeyPressProvider() {
    return this.nameTextBox;
  }

  @Override
  public HasKeyPressHandlers getPasswordTextKeyPressProvider() {
    return this.passwordTextBox;
  }

  @Override
  public HasKeyPressHandlers getUsernameTextKeyPressProvider() {
    return this.usernameTextBox;
  }

  @Override
  public HasClickHandlers getSubmitButton() {
    return this.signUpButton;
  }

  @Override
  public void showUsernameAvailability(boolean isUsernameAvailable) {
    if (isUsernameAvailable) {
      this.usernameErrorImage.setResource(resources.rightIcon());
      this.usernameErrorLabel.setText(USERNAME_AVAILABLE_MESSAGE);
    } else {
      this.usernameErrorImage.setResource(resources.wrongIcon());
      this.usernameErrorLabel.setText(USERNAME_NOT_AVAILABLE_MESSAGE);
    }
    
    this.usernameErrorImage.setVisible(true);
    this.usernameErrorLabel.setVisible(true);
  }

  @Override
  public void showUsernameAvailabilityCheckInProgress() {
    this.usernameErrorImage.setResource(resources.waitAnimation());
    this.usernameErrorLabel.setText(USERNAME_AVAILABLE_IN_PROGRESS_MESSAGE);
    this.usernameErrorImage.setVisible(true);
    this.usernameErrorLabel.setVisible(true);
  }

  @Override
  public void hideUsernameAvailabilityCheckInProgress() {
    this.usernameErrorImage.setVisible(false);
    this.usernameErrorLabel.setVisible(false);
  }

  @Override
  public void showServerErrorMessage() {
    this.messageImage.setResource(resources.wrongIcon());
    this.messageLabel.setText(AppResources.SERVER_ERROR);
    this.messageImage.setVisible(true);
    this.messageLabel.setVisible(true);
  }

  @Override
  public void clearErrorMessage() {
    this.messageImage.setVisible(false);
    this.messageLabel.setVisible(false);
  }

  @Override
  public void showSignUpFailure(String message) {
    this.messageImage.setResource(resources.wrongIcon());
    this.messageLabel.setText(message);
    this.messageImage.setVisible(true);
    this.messageLabel.setVisible(true);
  }

  @Override
  public void addToSlot(Object slot, Widget content) {
    // TODO Auto-generated method stub
  }

  @Override
  public void removeFromSlot(Object slot, Widget content) {
    // TODO Auto-generated method stub
  }

  @Override
  public void setInSlot(Object slot, Widget content) {
    // TODO Auto-generated method stub
  }
}
